<cfcomponent output="false">

	<cfset variables.queue = ArrayNew(1)/>
	<!--- TODO: Add Comparison support, test with various datatypes --->
	
	<cffunction name="init" output="false" returntype="PriorityQueue">
		<cfargument name="comparator" type="any" required="false" default="#defaultCompare#"/>
		<cfset variables.compare = arguments.comparator/>
		<cfreturn this/>
	</cffunction>
	
	<cffunction name="push" returntype="void" output="false" hint="adds an item to the queue.">
		<cfargument name="value" type="any" required="true"/>
		<!--- need to find proper insertation point here --->
		<cfif ArrayLEN(variables.queue) EQ 0>
			<!--- Empty Queue --->
			<cfset ArrayAppend(variables.queue, arguments.value)/>
		<cfelseif variables.compare(arguments.value, variables.queue[1])>
			<!--- item should be first --->
			<cfset ArrayPrepend(variables.queue, arguments.value)/>
		<cfelseif variables.compare(variables.queue[arrayLEN(variables.queue)], arguments.value)>
			<!--- item should be last --->
			<cfset ArrayAppend(variables.queue, arguments.value)/>
		<cfelse>
			<cfset inserted = false/>
			<cfloop from="#ArrayLEN(variables.queue)#" to="1" index="testItem" step="-1">
				<cfif variables.compare(variables.queue[testItem], arguments.value)>
					<cfset ArrayInsertAt(variables.queue, testItem+1, arguments.value)/>
					<cfset inserted = true/>
					<cfbreak/>
				</cfif>
			</cfloop>
		</cfif>
		<!--- <cfset ArrayAppend(variables.queue, arguments.value)/> --->
	</cffunction>

	<cffunction name="pop" returntype="any" output="false" hint="returns and removes the next item on the queue.">
		<cfset var result = variables.queue[1]/>
		<cfset ArrayDeleteAt(variables.queue,1)/>
		<cfreturn result/>
	</cffunction>
	
	<cffunction name="size" returntype="numeric" output="false">
		<cfreturn ArrayLEN(variables.queue)/>
	</cffunction>
	
	<cffunction name="top" returntype="any" output="false" hint="returns, but does not remove the next item on the queue.">
		<cfreturn variables.queue[1]/>
	</cffunction>
	
	<cffunction name="defaultCompare" output="false" returntype="boolean">
		<cfargument name="A" type="any" required="true"/>
		<cfargument name="B" type="any" required="true"/>
		<cfreturn A GT B/>
	</cffunction>
	
</cfcomponent>